package com.cloud.mkz.admin.api.util;

import com.cloud.mkz.admin.api.entity.RbacMenu;
import lombok.experimental.UtilityClass;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 菜单树工具类
 *
 * @author: KuangJianyu
 * @date: 2021-3-29
 */
@UtilityClass
public class TreeUtil {

    /**
     * 获取角色对应权限树
     * @param list
     * @return List<Map<String, Object>>
     */
    public List<Map<String, Object>> buildTree(List<RbacMenu> list, String rootPid){
        List<Map<String, Object>> result = new ArrayList<>();
        if(!CollectionUtils.isEmpty(list)){
            List<RbacMenu> parentList = list.stream().filter(item -> rootPid.equals(item.getParentId().toString())).collect(Collectors.toList());
            if(!CollectionUtils.isEmpty(parentList)){
                parentList.forEach(item->{
                    List<RbacMenu> sonTempList = list.stream().filter(tempItem -> item.getPkId().toString().equals(tempItem.getParentId().toString())).collect(Collectors.toList());
                    Map<String, Object> map = new HashMap<>();
                    map.put("id",item.getPkId());
                    map.put("title",item.getDisplayName());
                    if(item.getMenuType()==1){
                        map.put("spread", true);      //设置是否展开
                    }
                    if(item.getAssigned()==1&&(sonTempList==null||sonTempList.size()<1)){
                        map.put("checked", true);      //设置是否选中
                    }
                    //map是查询出来的根节点，list是所有的节点
                    getSonUseTree(map, list);
                    result.add(map);
                });
            }
        }
        return result;
    }

    /**
     * 递归获取角色对应菜单的子节点
     * @param map
     * @param list
     * @return Map<String,Object>
     */
    private Map<String,Object> getSonUseTree(Map<String,Object> map, List<RbacMenu> list){
        //用来存放所有孩子集合
        List<Map<String,Object>> sonList = new ArrayList<>();
        //选出某一个根节点下面的子树，递归。
        List<RbacMenu> son = list.stream().filter(item -> map.get("id").toString().equals(item.getParentId().toString())).collect(Collectors.toList());
        //如果此节点的孩子不为空，则把孩子放在map里面，并加入到孩子集合里面
        if(!son.isEmpty()){
            son.forEach(item->{
                List<RbacMenu> sonTempList = list.stream().filter(tempItem -> item.getPkId().toString().equals(tempItem.getParentId().toString())).collect(Collectors.toList());
                Map<String,Object> sonMap = new HashMap<>();
                sonMap.put("id",item.getPkId());
                sonMap.put("title",item.getDisplayName());
                if(item.getMenuType()==1){
                    sonMap.put("spread", true);      //设置是否展开
                }
                if(item.getAssigned()==1&&(sonTempList==null||sonTempList.size()<1)){
                    sonMap.put("checked", true);      //设置是否选中
                }
                sonList.add(sonMap);
                getSonUseTree(sonMap, list);
            });
        }

        if(!CollectionUtils.isEmpty(sonList)){
            map.put("children",sonList);
        }
        return map;
    }

    /**
     * 获取登录后的菜单树
     * @param list
     * @return List<Map<String, Object>>
     */
    public List<Map<String, Object>> getTreeInfo(List<RbacMenu> list, String rootPid){
        List<Map<String, Object>> result = new ArrayList<>();
        if(!CollectionUtils.isEmpty(list)){
            List<RbacMenu> parentList = list.stream().filter(item -> rootPid.equals(item.getParentId().toString())).collect(Collectors.toList());
            if(!CollectionUtils.isEmpty(parentList)){
                parentList.forEach(item->{
                    Map<String, Object> map = new HashMap<>();
                    map.put("id",item.getPkId());
                    map.put("pid",item.getParentId());
                    map.put("title",item.getDisplayName());
                    map.put("icon",item.getMenuIcon());
                    map.put("href",item.getMenuUrl());
                    map.put("target",item.getOpenType());
                    //map是查询出来的根节点，list是所有的节点
                    TreeUtil.getChildren(map, list);
                    result.add(map);
                });
            }
        }
        return result;
    }

    /**
     * 递归获取登录菜单的子节点
     * @param map
     * @param list
     * @return Map<String,Object>
     */
    public Map<String,Object> getChildren(Map<String,Object> map, List<RbacMenu> list){
        //用来存放所有孩子集合
        List<Map<String,Object>> sonList = new ArrayList<>();
        //选出某一个根节点下面的子树，递归。
        List<RbacMenu> son = list.stream().filter(item -> map.get("id").toString().equals(item.getParentId().toString())).collect(Collectors.toList());
        //如果此节点的孩子不为空，则把孩子放在map里面，并加入到孩子集合里面
        if(!son.isEmpty()){
            son.forEach(item->{
                Map<String,Object> sonMap = new HashMap<>();
                sonMap.put("id",item.getPkId());
                sonMap.put("pid",item.getParentId());
                sonMap.put("title",item.getDisplayName());
                sonMap.put("icon",item.getMenuIcon());
                sonMap.put("href",item.getMenuUrl());
                sonMap.put("target",item.getOpenType());
                sonList.add(sonMap);
                getChildren(sonMap, list);
            });
        }

        if(!CollectionUtils.isEmpty(sonList)){
            map.put("child",sonList);
        }
        return map;
    }

    /**
     * 递归组装树结构
     * @param menus
     * @param result
     * @return Object
     */
    private Object buildTree(List<RbacMenu> menus, List<Map<String, Object>> result) {
        for(RbacMenu m : menus){
            HashMap<String, Object> map = new HashMap<>();
            map.put("id", m.getPkId());
            map.put("title", m.getDisplayName());
            if(m.getMenuType()==1){
                map.put("spread", true);
            }
            if(m.getAssigned()==1){
                map.put("checked", true);
            }
            List<Map<String, Object>> tempResult = new ArrayList<>();
            List<RbacMenu> children = m.getChildren();
            //这里可以根据自己需求判断节点默认选中
            if(m.getParentId() != null && (m.getChildren().size() == 0||m.getChildren()==null)){
                map.put("checked", true);
            }
            if(null!=children){
                map.put("children", buildTree(children, tempResult));
                result.add(map);
            }
        }
        return result;
    }
}
